/*
 * $Id: ctype_unicode.c,v 1.9 2005-04-24 07:48:16 bacon Exp $
 */

#include <xp/bas/ctype_unicode.h>
#include <xp/bas/ctype_unicode_trait.c>
#include <xp/bas/ctype_unicode_case.c>

#define TRAIT_MAP_INDEX(c) ((c) / xp_countof(xp_unicode_trait_page_0000))
#define TRAIT_PAGE_INDEX(c) ((c) % xp_countof(xp_unicode_trait_page_0000))

#define CASE_MAP_INDEX(c) ((c) / xp_countof(xp_unicode_case_page_0000))
#define CASE_PAGE_INDEX(c) ((c) % xp_countof(xp_unicode_case_page_0000))

#define XP_UNICODE_ISTYPE(c,type) \
	((c) >= 0 && (c) <= XP_CTYPE_UNICODE_TRAIT_MAX && \
	 (xp_unicode_trait_map[TRAIT_MAP_INDEX(c)][TRAIT_PAGE_INDEX(c)] & (type)) != 0)

xp_bool_t xp_unicode_istype (xp_wcint_t c, int type)
{
	return XP_UNICODE_ISTYPE (c, type);
}

xp_bool_t xp_unicode_isupper (xp_wcint_t c)
{
	return XP_UNICODE_ISTYPE (c, XP_CHAR_TRAIT_UPPER);
}

xp_bool_t xp_unicode_islower (xp_wcint_t c)
{
	return XP_UNICODE_ISTYPE (c, XP_CHAR_TRAIT_LOWER);
}

xp_bool_t xp_unicode_isalpha (xp_wcint_t c)
{
	return XP_UNICODE_ISTYPE (c, XP_CHAR_TRAIT_ALPHA);
}

xp_bool_t xp_unicode_isdigit (xp_wcint_t c)
{
	return XP_UNICODE_ISTYPE (c, XP_CHAR_TRAIT_DIGIT);
}

xp_bool_t xp_unicode_isxdigit (xp_wcint_t c)
{
	return XP_UNICODE_ISTYPE (c, XP_CHAR_TRAIT_XDIGIT);
}

xp_bool_t xp_unicode_isalnum (xp_wcint_t c)
{
	return XP_UNICODE_ISTYPE (c, XP_CHAR_TRAIT_ALNUM);
}

xp_bool_t xp_unicode_isspace (xp_wcint_t c)
{
	return XP_UNICODE_ISTYPE (c, XP_CHAR_TRAIT_SPACE);
}

xp_bool_t xp_unicode_isprint (xp_wcint_t c)
{
	return XP_UNICODE_ISTYPE (c, XP_CHAR_TRAIT_PRINT);
}

xp_bool_t xp_unicode_isgraph (xp_wcint_t c)
{
	return XP_UNICODE_ISTYPE (c, XP_CHAR_TRAIT_GRAPH);
}

xp_bool_t xp_unicode_iscntrl (xp_wcint_t c)
{
	return XP_UNICODE_ISTYPE (c, XP_CHAR_TRAIT_CNTRL);
}

xp_bool_t xp_unicode_ispunct (xp_wcint_t c)
{
	return XP_UNICODE_ISTYPE (c, XP_CHAR_TRAIT_PUNCT);
}

xp_wcint_t xp_unicode_toupper (xp_wcint_t c)
{
	if (c >= 0 && c <= XP_CTYPE_UNICODE_CASE_MAX) {
	 	xp_unicode_case_page_t* page;
		page = xp_unicode_case_map[CASE_MAP_INDEX(c)];
		return c - page[CASE_PAGE_INDEX(c)].upper;
	}
	return c;
}

xp_wcint_t xp_unicode_tolower (xp_wcint_t c)
{
	if (c >= 0 && c <= XP_CTYPE_UNICODE_CASE_MAX) {
	 	xp_unicode_case_page_t* page;
		page = xp_unicode_case_map[CASE_MAP_INDEX(c)];
		return c + page[CASE_PAGE_INDEX(c)].lower;
	}
	return c;
}
